﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Xml;

namespace Vapeur
{
    class Engine
    {
        XmlTextReader reader;
        private string searchString;
        private SearchType engineSearchType;

        public string Artist { get; set; }
        public List<string> Similar { get; set; }
        public List<Track> Tracks { get; set; }

        public Engine(string searchTerm, SearchType searchType)
        {
            this.engineSearchType = searchType;
            this.searchString = searchTerm;

            this.Tracks = new List<Track>();
            this.Similar = new List<string>();


            if (searchType == SearchType.Artist)
            {
                this.readXml(ArtistInfoType.Tracks);
                this.readXml(ArtistInfoType.Similar);
            }
            else if (searchType == SearchType.Tag)
            {
                this.readXmlTag(ArtistInfoType.Tracks);
                this.readXmlTag(ArtistInfoType.Similar);
            }
        }

        private void readXmlTag(ArtistInfoType infoType)
        {
            string URLString = "http://ws.audioscrobbler.com/1.0/tag/" + searchString;

            string currentElement = null;
            string currentTrack = null;

            if (infoType == ArtistInfoType.Tracks)
                URLString += "/toptracks.xml";
            else if (infoType == ArtistInfoType.Similar)
                URLString += "/topartists.xml";

            try
            {
                reader = new XmlTextReader(URLString);

                while (reader.Read())
                {
                    switch (reader.NodeType)
                    {
                        case XmlNodeType.Element: // The node is an element.
                            currentElement = reader.Name;
                            while (reader.MoveToNextAttribute()) // Read the attributes.
                            {
                                if (reader.Name == "tag")
                                {
                                    this.Artist = reader.Value;
                                    break;
                                }

                                if (currentElement == "track" && reader.Name == "name")
                                {
                                    currentTrack = reader.Value;
                                }
                                else if (currentElement == "artist" && reader.Name == "name")
                                {
                                    if (infoType == ArtistInfoType.Tracks)
                                    {
                                        Track track = new Track();
                                        track.Artist = reader.Value;
                                        track.Name = currentTrack;
                                        track.SearchType = this.engineSearchType;
                                        this.Tracks.Add(track);
                                    }
                                    else if (infoType == ArtistInfoType.Similar)
                                    {
                                        this.Similar.Add(reader.Value);
                                    }
                                }
                            }
                            break;

                        case XmlNodeType.Text: //Display the text in each element.
                            if (currentElement == "name")
                            {
                                if (infoType == ArtistInfoType.Tracks)
                                {
                                    Track track = new Track();
                                    track.Artist = this.Artist;
                                    track.Name = reader.Value;
                                    track.SearchType = this.engineSearchType;
                                    this.Tracks.Add(track);
                                }
                                else if (infoType == ArtistInfoType.Similar)
                                    this.Similar.Add(reader.Value);

                            }
                            break;
                    }
                }
            }

            catch (Exception)
            {
                //TODO: Warning!! blackholing exception
            }
        }


        private void readXml(ArtistInfoType infoType)
        {
            string URLString = "http://ws.audioscrobbler.com/1.0/artist/" + searchString;

            string currentElement = null;

            if (infoType == ArtistInfoType.Tracks)
                URLString += "/toptracks.xml";
            else if (infoType == ArtistInfoType.Similar)
                URLString += "/similar.xml";

            try
            {
                reader = new XmlTextReader(URLString);

                while (reader.Read())
                {
                    switch (reader.NodeType)
                    {
                        case XmlNodeType.Element: // The node is an element.
                            currentElement = reader.Name;
                            while (reader.MoveToNextAttribute()) // Read the attributes.
                            {
                                if (reader.Name == "artist")
                                {
                                    this.Artist = reader.Value;
                                    break;
                                }
                            }
                            break;

                        case XmlNodeType.Text: //Display the text in each element.
                            if (currentElement == "name")
                            {
                                if (infoType == ArtistInfoType.Tracks)
                                {
                                    Track track = new Track();
                                    track.Artist = this.Artist;
                                    track.Name = reader.Value;
                                    track.SearchType = this.engineSearchType;
                                    this.Tracks.Add(track);
                                }
                                else if (infoType == ArtistInfoType.Similar)
                                    this.Similar.Add(reader.Value);

                            }
                            break;
                    }
                }
            }

            catch (Exception)
            {
                //TODO: Warning!! blackholing exception
            }
        }
    }
}
